//
//  StatisticsComputator.h
//  GPUProcessingTesting
//
//  Created by kadlubek47 on 19.08.2013.
//  Copyright (c) 2013 kadlubek47. All rights reserved.
//

#ifndef GPUProcessingTesting_StatisticsComputator_h
#define GPUProcessingTesting_StatisticsComputator_h

#include "TrialsSet.h"
#include <algorithm>    // std::sort


class StatisticsComputator {
public:
    
    class StandardStruct {
    public:
        double onTime               = -1;
        double onTime_percentage    = -1;
        
        double average              = -1;
        
        double minimum              = -1;
        double quartile1            = -1;
        double median               = -1;
        double quartile3            = -1;
        double maximum              = -1;
        
    };
    
    static StandardStruct standard(TrialsSet& trialsSet) {
        
        //Result, sortedTrials
        StandardStruct result;
        size_t numOfTrials = trialsSet.get_trialsNumber();
        std::vector<double> sortedTrials = trialsSet.get_trials();
        std::sort ( sortedTrials.begin(), sortedTrials.end() );
        //.
        
        //averageTrialValue
        double sum = 0;
        for(size_t trialNum = 0; trialNum < numOfTrials; ++trialNum )
            sum += trialsSet.get_trial( trialNum );
        
        result.average = sum / (double)numOfTrials;
        //.
        
        //minimal, median, maximum, quartile1, quartile3
        result.minimum      = sortedTrials[0];
        result.quartile1    = sortedTrials[numOfTrials/4];
        result.median       = sortedTrials[numOfTrials/2];
        result.quartile3    = sortedTrials[numOfTrials*3/4];
        result.maximum      = sortedTrials[numOfTrials-1];
        //.
        
        //numOfBlocksOnTime
        unsigned int blockSize = boost::any_cast<unsigned int> (    trialsSet.get_description(std::string(BLOCK_SIZE))      );
        unsigned int sampleRate= boost::any_cast<unsigned int> (    trialsSet.get_description(std::string(SAMPLE_RATE))     );
        
        double latencyValue = (double) blockSize /  (double) sampleRate;
        result.onTime = 0;
        for(size_t trialNum = 0; trialNum < numOfTrials; ++trialNum )
            if( trialsSet.get_trial( trialNum ) < latencyValue )
                ++result.onTime;
        
        result.onTime_percentage = (double)result.onTime / (double)numOfTrials ;
        //.
        
        return result;
    }
    
};


#endif
